﻿// Operations and events related to validating an element
define([
    'Wjs/ui/widgets/validation/RequiredValidator',
    'Wjs/ui/widgets/validation/MaxLengthValidator',
    'Wjs/ui/widgets/validation/EmailValidator',
    'Wjs/ui/widgets/validation/UrlValidator'
],
function () {
    'use strict';

    return Wjs.defineOnce({

        type: 'Validatable',

        internal: {

            construct: function () {

                this.validators = []; // The validators of the field
            }
        },

        setDisplay: function(fieldName) {

            this.display = fieldName;

            return this;
        },

        // Adds a validator to this field
        addValidator: function (validator) {

            if (Wjs.isString(validator)) {

                validator = Wjs.getType('validatorManager').get(validator);
            }

            this.validators.push(validator);

            return this;
        },

        // Validates the field using the attached validators
        validate: function (validationContext, validateOnBlur) {
            var success = true;

            if (this.validators) {

                this.validators.forEach(function (validator) {

                    if (!validateOnBlur ||
                        (validateOnBlur && validator.validateOnBlur)) {

                        if (!validator.validate(this, validationContext)) {

                            success = false;
                        }
                    }

                },
                this);
            }

            return success;
        },

        validateOnBlur: function () {
            var me = this,
                errors = [];

            if (me.validators) {

                me.validators.forEach(function (validator) {

                    if (validator.validateOnBlur) {

                        validator.validateOnBlur(me, errors);
                    }
                });

                if (errors.length > 0) {

                    Wjs.validationSummary.setErrors(errors);

                    Wjs.validationSummary.show();
                }
            }
        },

        // Restricts the input of characters if they do not match the validators rules
        restrictInput: function (evt) {
            var me = this,
                validator = null,
                success = true;

            if (me.validators) {

                for (var i = 0, length = me.validators.length; i < length; ++i) {
                    validator = me.validators[i];

                    if (validator.restrictInput &&
                        !validator.restrictInput(me, evt.keyCode)) {
                        success = false;
                        break; // Do not continue restricting
                    }
                }
            }

            if (!success) { // Do not accept the input
                evt.preventDefault();
            }
        }


    });

});